home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / nos042_s / slip.c < prev    next >
C/C++ Source or Header  |  1994-09-16  |  6KB  |  258 lines

  1. /* SLIP (Serial Line IP) encapsulation and control routines.
  2.  * Copyright 1991 Phil Karn
  3.  *
  4.  * Van Jacobsen header compression hooks added by Katie Stevens, UC Davis
  5.  *
  6.  *    - Feb 1991    Bill_Simpson@um.cc.umich.edu
  7.  *            reflect changes to header compression calls
  8.  *            revise status display
  9.  *
  10.  * ATARI Version by David Nash - dnash@chaos.demon.co.uk
  11.  *
  12.  * Add __stdargs to asy_rx  
  13.  */
  14. #include <stdio.h>
  15. #include "global.h"
  16. #include "config.h"
  17. #include "mbuf.h"
  18. #include "iface.h"
  19. #include "ip.h"
  20. #include "slhc.h"
  21. #include "asy.h"
  22. #include "slip.h"
  23. #include "trace.h"
  24.  
  25. static struct mbuf *slip_decode __ARGS((struct slip *sp,char c));
  26. static struct mbuf *slip_encode __ARGS((struct mbuf *bp));
  27.  
  28. /* Slip level control structure */
  29. struct slip Slip[ASY_MAX];
  30.  
  31. /* Send routine for point-to-point slip */
  32. int
  33. slip_send(bp,iface,gateway,prec,del,tput,rel)
  34. struct mbuf *bp;    /* Buffer to send */
  35. struct iface *iface;    /* Pointer to interface control block */
  36. int32 gateway;        /* Ignored (SLIP is point-to-point) */
  37. int prec;
  38. int del;
  39. int tput;
  40. int rel;
  41. {
  42. #ifdef VJCOMPRESS
  43.     register struct slip *sp;
  44.     int type;
  45. #endif
  46.     if(iface == NULLIF){
  47.         free_p(bp);
  48.         return -1;
  49.     }
  50. #ifdef VJCOMPRESS
  51.     sp = &Slip[iface->xdev];
  52.     if (sp->escaped & SLIP_VJCOMPR) {
  53.         /* Attempt IP/ICP header compression */
  54.         type = slhc_compress(sp->slcomp,&bp,TRUE);
  55.         bp->data[0] |= type;
  56.     }
  57. #endif
  58.     return (*iface->raw)(iface,bp);
  59. }
  60. /* Send a raw slip frame */
  61. int
  62. slip_raw(iface,bp)
  63. struct iface *iface;
  64. struct mbuf *bp;
  65. {
  66.     struct mbuf *bp1;
  67.  
  68.     dump(iface,IF_TRACE_OUT,Slip[iface->xdev].type,bp);
  69.     iface->rawsndcnt++;
  70.     iface->lastsent = secclock();
  71.     if((bp1 = slip_encode(bp)) == NULLBUF){
  72.         return -1;
  73.     }
  74.     if (iface->trace & IF_TRACE_RAW)
  75.         raw_dump(iface,-1,bp1);
  76.     return Slip[iface->xdev].send(iface->dev,bp1);
  77. }
  78. /* Encode a packet in SLIP format */
  79. static
  80. struct mbuf *
  81. slip_encode(bp)
  82. struct mbuf *bp;
  83. {
  84.     struct mbuf *lbp;    /* Mbuf containing line-ready packet */
  85.     register char *cp;
  86.     int c;
  87.  
  88.     /* Allocate output mbuf that's twice as long as the packet.
  89.      * This is a worst-case guess (consider a packet full of FR_ENDs!)
  90.      */
  91.     lbp = alloc_mbuf((int16)(2*len_p(bp) + 2));
  92.     if(lbp == NULLBUF){
  93.         /* No space; drop */
  94.         free_p(bp);
  95.         return NULLBUF;
  96.     }
  97.     cp = lbp->data;
  98.  
  99.     /* Flush out any line garbage */
  100.     *cp++ = FR_END;
  101.  
  102.     /* Copy input to output, escaping special characters */
  103.     while((c = PULLCHAR(&bp)) != -1){
  104.         switch(c){
  105.         case FR_ESC:
  106.             *cp++ = FR_ESC;
  107.             *cp++ = T_FR_ESC;
  108.             break;
  109.         case FR_END:
  110.             *cp++ = FR_ESC;
  111.             *cp++ = T_FR_END;
  112.             break;
  113.         default:
  114.             *cp++ = c;
  115.         }
  116.     }
  117.     *cp++ = FR_END;
  118.     lbp->cnt = cp - lbp->data;
  119.     return lbp;
  120. }
  121. /* Process incoming bytes in SLIP format
  122.  * When a buffer is complete, return it; otherwise NULLBUF
  123.  */
  124. static struct mbuf *slip_decode(
  125.     struct slip *sp,
  126.     char c)                    /* Incoming character */
  127. {
  128.     struct mbuf *bp;
  129.  
  130.     switch(uchar(c)){
  131.     case FR_END:
  132.         bp = sp->rbp_head;
  133.         sp->rbp_head = NULLBUF;
  134.         return bp;    /* Will be NULLBUF if empty frame */
  135.     case FR_ESC:
  136.         sp->escaped |= SLIP_FLAG;
  137.         return NULLBUF;
  138.     }
  139.     if(sp->escaped & SLIP_FLAG){
  140.         /* Translate 2-char escape sequence back to original char */
  141.         sp->escaped &= ~SLIP_FLAG;
  142.         switch(uchar(c)){
  143.         case T_FR_ESC:
  144.             c = FR_ESC;
  145.             break;
  146.         case T_FR_END:
  147.             c = FR_END;
  148.             break;
  149.         default:
  150.             sp->errors++;
  151.             break;
  152.         }
  153.     }
  154.     /* We reach here with a character for the buffer;
  155.      * make sure there's space for it
  156.      */
  157.     if(sp->rbp_head == NULLBUF){
  158.         /* Allocate first mbuf for new packet */
  159.         if((sp->rbp_tail = sp->rbp_head = alloc_mbuf(SLIP_ALLOC)) == NULLBUF)
  160.             return NULLBUF; /* No memory, drop */
  161.         sp->rcp = sp->rbp_head->data;
  162.     } else if(sp->rbp_tail->cnt == SLIP_ALLOC){
  163.         /* Current mbuf is full; link in another */
  164.         if((sp->rbp_tail->next = alloc_mbuf(SLIP_ALLOC)) == NULLBUF){
  165.             /* No memory, drop whole thing */
  166.             free_p(sp->rbp_head);
  167.             sp->rbp_head = NULLBUF;
  168.             return NULLBUF;
  169.         }
  170.         sp->rbp_tail = sp->rbp_tail->next;
  171.         sp->rcp = sp->rbp_tail->data;
  172.     }
  173.     /* Store the character, increment fragment and total
  174.      * byte counts
  175.      */
  176.     *sp->rcp++ = c;
  177.     sp->rbp_tail->cnt++;
  178.     return NULLBUF;
  179. }
  180.  
  181.  
  182. /* Process SLIP line input */
  183. void
  184. __stdargs asy_rx(xdev,p1,p2)
  185. int xdev;
  186. void *p1;
  187. void *p2;
  188. {
  189.     int c;
  190.     struct mbuf *bp;
  191.     register struct slip *sp;
  192.     int cdev;
  193.  
  194.     sp = &Slip[xdev];
  195.     cdev = sp->iface->dev;
  196.  
  197.     while ( (c = sp->get(cdev)) != -1 ) {
  198.         if((bp = slip_decode(sp,(char)c)) == NULLBUF)
  199.             continue;    /* More to come */
  200.  
  201. #ifdef VJCOMPRESS
  202.         if (sp->iface->trace & IF_TRACE_RAW)
  203.             raw_dump(sp->iface,IF_TRACE_IN,bp);
  204.  
  205.         if (sp->escaped & SLIP_VJCOMPR) {
  206.             if ((c = bp->data[0]) & SL_TYPE_COMPRESSED_TCP) {
  207.                 if ( slhc_uncompress(sp->slcomp, &bp) <= 0 ) {
  208.                     free_p(bp);
  209.                     sp->errors++;
  210.                     continue;
  211.                 }
  212.             } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
  213.                 bp->data[0] &= 0x4f;
  214.                 if ( slhc_remember(sp->slcomp, &bp) <= 0 ) {
  215.                     free_p(bp);
  216.                     sp->errors++;
  217.                     continue;
  218.                 }
  219.             }
  220.         }
  221. #endif
  222.         if ( net_route( sp->iface, sp->type, bp ) != 0 ) {
  223.             free_p(bp);
  224.         }
  225.     }
  226.     free_p(bp);
  227. }
  228.  
  229.  
  230.  
  231. /* Show serial line status */
  232. void
  233. slip_status(iface)
  234. struct iface *iface;
  235. {
  236.     struct slip *sp;
  237.  
  238.     if (iface->xdev > SLIP_MAX)
  239.         /* Must not be a SLIP device */
  240.         return;
  241.  
  242.     sp = &Slip[iface->xdev];
  243.     if (sp->iface != iface)
  244.         /* Must not be a SLIP device */
  245.         return;
  246.  
  247.     tprintf("  IN:\t%lu pkts\n", iface->rawrecvcnt);
  248. #ifdef VJCOMPRESS
  249.     slhc_i_status(sp->slcomp);
  250. #endif
  251.     tprintf("  OUT:\t%lu pkts\n", iface->rawsndcnt);
  252. #ifdef VJCOMPRESS
  253.     slhc_o_status(sp->slcomp);
  254. #endif
  255. }
  256.  
  257.  
  258.